package com.turing.post.tuxedo.util;

import java.io.Serializable;
import java.util.Date;

import org.jdom2.Document;
import org.jdom2.Element;

import com.turing.post.organization.util.IssueCompany;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.SHA1;

/**
 * 商户交易请求基类
 * 
 * @author yxb
 * 
 */
@SuppressWarnings("serial")
public class TransRequest implements Serializable {
	/**
	 * 发卡商
	 */
	public IssueCompany issueCompany = null;

	/**
	 * 交易码
	 */
	public String tranCode = "";

	/**
	 * 商户号
	 */
	public String merchantNo = "";

	/**
	 * 交易日期
	 */
	public Date tranDate = null;

	/**
	 * 交易请求时间(YYYYMMDDHHMISS)
	 */
	public Date tranTime = null;

	/**
	 * 商户POS
	 */
	public PosObj posObj = new PosObj();

	/**
	 * 请求流水号(最长不超过40位)
	 */
	public String reqSeqNo = "";

	/**
	 * 商户分支机构编号(可选)
	 */
	public String brchNo = "";

	/**
	 * 商户分支机构名称(可选)
	 */
	public String brchName = "";

	/**
	 * 商户操作员号(可选)
	 */
	public String tellerNo = "";

	/**
	 * 商户操作员姓名(可选)
	 */
	public String tellerName = "";

	/**
	 * 交易MAC
	 */
	public String tranMac = "";

	/**
	 * 当前服务器时间
	 */
	public Date curSysDateTime = null;

	/**
	 * 交易KEY
	 */
	public String tranKey = TransXmlHelper.XML_DEFAULT_TRANKEY;

	/**
	 * 计算MAC的字符串
	 */
	public StringBuilder macBuf = null;

	/**
	 * 产生计算MAC的域
	 */
	protected void generateMacField() {
	}

	/**
	 * 验证MAC
	 * 
	 * @return
	 */
	public boolean verifyMac() {
		macBuf = new StringBuilder();
		// 本类
		appendMacField(tranCode);
		appendMacField(merchantNo);
		appendMacField(PCPSUtil.getStringYMDHMSPackedByDate(tranTime));

		// 子类
		generateMacField();
		macBuf.append(tranKey);
		String macstr = macBuf.toString();
		macstr = new SHA1().getDigestOfString(macstr.getBytes());
		if (!macstr.equalsIgnoreCase(tranMac)) {
			PCPSUtil.Log("XML tranMac:[" + tranMac + "]");
			PCPSUtil.Log("XML calc field:[" + macBuf.toString() + "]");
			PCPSUtil.Log("XML calc result:[" + macstr + "]");
			return false;
		}

		return true;
	}

	/**
	 * 增加计算MAC的域
	 * 
	 * @param buff
	 */
	public void appendMacField(String buff) {
		macBuf.append(PCPSUtil.isEmpty(buff) ? "" : buff.trim());
	}

	/**
	 * 解析交易请求私有报文体
	 * 
	 * @param reqBody
	 * @throws Exception
	 */
	protected void parseReqBodyXml(Element reqBody)
			throws PCPSApplicationException {
	}

	/**
	 * 解析XML请求报文
	 * 
	 * @param doc
	 */
	public void parseXml(byte[] ibuf) throws PCPSApplicationException {
		Document doc = TransXmlHelper.getXmlDocumentFromBuffer(ibuf);
		Element root = doc.getRootElement();
		if (!PCPSUtil.compareObject(root.getName(),
				TransXmlHelper.XML_NODE_TransRequest))
			ParaseException.TransParamException("invalid XML Root Node Name[" + root.getName()
					+ "]!");
		// trancode
		tranCode = TransXmlHelper.getMandatoryString(root,
				TransXmlHelper.XML_NODE_TranCode);
		// merchantNo
		merchantNo = TransXmlHelper.getMandatoryString(root,
				TransXmlHelper.XML_NODE_MerchantNo);

		// 交易日期(YYYYMMDD)
		String str = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_TranDate);
		if (!PCPSUtil.isEmpty(str))
			try {
				tranDate = PCPSUtil.parsePackedYMDDateTime(str);
			} catch (Exception e) {
				ParaseException.TransParamException("TRANDATE[" + str + "]无效!");
			}
		else
			tranDate = null;

		// 交易请求时间(YYYYMMDDHHMISS)
		str = TransXmlHelper.getMandatoryString(root,
				TransXmlHelper.XML_NODE_TranTime);
		try {
			tranTime = PCPSUtil.parseDateTime(str);
		} catch (Exception e) {
			ParaseException.TransParamException("TRANTIME[" + str + "]无效!");
		}

		// POS
		posObj.parsePosObj(root);

		// 请求流水号
		reqSeqNo = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_ReqSeqNo);

		// 商户分支机构号(可选)
		brchNo = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_BrchNo);

		// 商户分支机构名称(可选)
		brchName = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_BrchName);

		// 商户操作员号(可选)
		tellerNo = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_TellerNo);

		// 商户操作员姓名(可选)
		tellerName = TransXmlHelper.getOptionalString(root,
				TransXmlHelper.XML_NODE_TellerName);

		// tranMac
		tranMac = TransXmlHelper.getMandatoryString(root,
				TransXmlHelper.XML_NODE_TranMac);

		// 解析交易私有部门
		Element reqBody = root.getChild(TransXmlHelper.XML_NODE_ReqBody);
		if (reqBody != null)
			parseReqBodyXml(reqBody);
	}

	/**
	 *将tuxedo client传来的XML字节数组报文中检索出交易码
	 * 
	 * @param ibuf
	 *            输入字节数组
	 * @return 交易码
	 */
	public static String getTranCodeFromBuffer(byte[] ibuf)
			throws PCPSApplicationException {
		// 检查ibuf是否为空
		if (ibuf == null || ibuf.length < 32)
			ParaseException.TransParamException("ibuf is NULL or Length invalidate!");
		Document doc = TransXmlHelper.getXmlDocumentFromBuffer(ibuf);
		Element root = doc.getRootElement();
		if (!PCPSUtil.compareObject(root.getName(),
				TransXmlHelper.XML_NODE_TransRequest))
			ParaseException.TransParamException("invalid XML Root Node Name[" + root.getName()
					+ "]!");
		Element tranCode_el = root.getChild(TransXmlHelper.XML_NODE_TranCode);
		String tranCode = tranCode_el.getTextTrim();
		if (PCPSUtil.isEmpty(tranCode))
			ParaseException.TransParamException("invalid TranCode[" + tranCode + "]!");
		return tranCode;
	}
}
